﻿using AMMVVMLibrary.Portable;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace AMMVVMLibrary.W8
{
    public class NavigationService : INavigationService
    {
        //public NavigationService()
        //{
        //}

        public NavigationService(Assembly assembly = null)
        {
            _assembly = assembly;
            //ViewModelRouting = null;
        }

        public Assembly _assembly;

        /// <summary> 
        /// Gets the root frame. 
        /// </summary> 
        private static Frame RootFrame
        {
            get { return Window.Current.Content as Frame; }
        }

        /// <summary> 
        /// Gets a value indicating whether can go back. 
        /// </summary> 
        public bool CanGoBack
        {
            get
            {
                return RootFrame.CanGoBack;
            }
        }

        /// <summary> 
        /// The go back. 
        /// </summary> 
        public void GoBack()
        {
            RootFrame.GoBack();
        }

        /// <summary> 
        /// Navigates the specified parameter. 
        /// </summary> 
        /// <typeparam name="TDestinationViewModel"> 
        /// The type of the destination view model. 
        /// </typeparam> 
        /// <param name="parameter"> 
        /// The parameter. 
        /// </param> 
        public void Navigate<TDestinationViewModel>(object parameter)
        {
            Type dest = null;
            if (ViewModelRouting != null && ViewModelRouting.ContainsKey(typeof(TDestinationViewModel)))
                dest = ViewModelRouting[typeof(TDestinationViewModel)];
            else if (_assembly != null)
                dest = ResolveView(typeof(TDestinationViewModel));
            else
                throw new ArgumentException("Either specify the ViewModelRouting or pass your Assembly for automatic view resolving.");

            RootFrame.Navigate(dest, parameter);
        }

        /// <summary>
        /// Resolve the view name automagically. Needs more testing
        /// </summary>
        /// <param name="viewModelType"></param>
        /// <returns></returns>
        public Type ResolveView(Type viewModelType)
        {
            var viewModelName = viewModelType.Name;
            var viewModelSplit = viewModelName.Split(new string[] { "ViewModel" }, StringSplitOptions.RemoveEmptyEntries);
            var pageName = viewModelSplit.First();
            return _assembly.ExportedTypes.Single(t => t.Name == pageName);
        }

        /// <summary>
        /// The view model routing. 
        /// Example
        /// = new Dictionary<Type, Type>() 
        /// { 
        ///     { typeof(TitlesViewModel), typeof(TitlesPage) }, 
        ///     { typeof(TitleDetailsViewModel), typeof(TitleDetailsPage) } 
        /// }; 
        /// </summary>
        public IDictionary<Type, Type> ViewModelRouting
        {
            get;
            set;
        }

    }
}
